// 饮食营养相关控制器
const Food = require("../../models/Food");
const Sport = require("../../models/Sport");
const Current = require("../../models/Current");
const Do = require("../../models/Do");
const DateModel = require("../../models/Date");
const { calculateNutrition, calculateSportBurn } = require("./utils");

/**
 * 填充食物详细信息
 * 为饮食记录中的每个食物添加 food_name 和营养数据
 */
async function populateFoodDetails(eatData) {
  const mealTypes = ['breakfast', 'lunch', 'dinner', 'snacks'];
  
  for (const mealType of mealTypes) {
    if (!eatData[mealType] || eatData[mealType].length === 0) continue;
    
    for (let i = 0; i < eatData[mealType].length; i++) {
      const meal = eatData[mealType][i];
      if (!meal.food_id) continue;
      
      try {
        // 尝试从 Food 模型查找
        let food = await Food.findById(meal.food_id);
        if (!food) {
          // 如果不是食物，可能是运动
          food = await Sport.findById(meal.food_id);
        }
        
        if (food) {
          // 添加食物名称
          meal.food_name = food.name;
          
          // 查找对应的单位信息
          const component = food.components.find(c => c.unit_name === meal.unit_name);
          if (component) {
            // 计算实际营养值（单位营养值 * 食用数量）
            meal.calorie = Math.round((component.calorie || 0) * meal.eat_num);
            meal.fat = Math.round((component.fat || 0) * meal.eat_num * 10) / 10;
            meal.carbohydrate = Math.round((component.carbohydrate || 0) * meal.eat_num * 10) / 10;
            meal.protein = Math.round((component.protein || 0) * meal.eat_num * 10) / 10;
          }
        }
      } catch (err) {
        console.error(`填充食物信息失败，food_id: ${meal.food_id}`, err.message);
      }
    }
  }
}

/**
 * 更新数据（饮食或运动）
 */
async function updateData(req, res) {
  try {
    const { openid, day } = req.query;
    let model;
    
    if (req.body.type === 1) {
      // 添加运动记录 - 无论请求的是哪个模型，type=1 都表示运动
      let data = await Do.findOne({ openid });
      
      if (!data) {
        // 如果用户没有运动记录，创建一个新的
        data = new Do({
          openid,
          exercise: 5000,
          sport: [],
          score: {}
        });
      }
      
      data.sport.push(req.body);
      
      // 重新计算今日运动消耗
      await calculateSportBurn(data);
      
      model = await Do.findOneAndUpdate({ openid }, data, { new: true, upsert: true });
      
    } else if (req.Model.modelName === "Eat" && !req.body.data) {
      // 添加食物到饮食记录
      const today = day || new Date().toISOString().split('T')[0];
      let data = await req.Model.findOne({ openid, date: today });
      
      if (!data) {
        // 如果今天还没有饮食记录，创建一个新的
        const User = require("../../models/User");
        const userInfo = await User.findOne({ openid });
        
        if (!userInfo) {
          return res.status(404).send({
            success: false,
            message: '未找到用户信息，请先登录'
          });
        }
        
        data = new req.Model({
          openid,
          date: today,
          data: today, // 兼容旧字段
          eat_score: 0,
          exercise: 1.37, // 默认中度运动
          breakfast: [],
          lunch: [],
          dinner: [],
          snacks: [],
          score: {
            calorie_target: 0,
            fat_target: 0,
            carbohydrate_target: 0,
            protein_target: 0,
            calorie_today: 0,
            fat_today: 0,
            carbohydrate_today: 0,
            protein_today: 0,
          },
        });
      }
      
      // 添加食物到对应的餐次
      switch (req.body.eat_type) {
        case 0:
          data.breakfast.push(req.body);
          break;
        case 1:
          data.lunch.push(req.body);
          break;
        case 2:
          data.dinner.push(req.body);
          break;
        default:
          data.snacks.push(req.body);
          break;
      }
      
      // 重新计算今日营养摄入
      await calculateNutrition(data);
    
      // 保存或更新饮食记录
      if (data._id) {
        model = await req.Model.findOneAndUpdate({ openid, date: today }, data, { new: true });
      } else {
        model = await data.save();
      }
      
      // 同时在 Date 表中添加日期记录（如果不存在）
      try {
        await DateModel.findOneAndUpdate(
          { openid, date: today },
          { openid, date: today },
          { upsert: true, new: true }
        );
      } catch (err) {
        console.log('Date 记录已存在或创建失败:', err.message);
      }
    } else {
      // 普通更新
      if (req.Model.modelName === "Eat") {
        // Eat 模型需要按日期查询
        const today = day || new Date().toISOString().split('T')[0];
        model = await req.Model.findOneAndUpdate({ openid, date: today }, req.body, { new: true });
        
        // 如果包含exercise字段或其他需要重新计算营养的字段，重新计算营养目标
        if (req.body.exercise !== undefined || req.body.breakfast !== undefined || 
            req.body.lunch !== undefined || req.body.dinner !== undefined || req.body.snacks !== undefined) {
          let data = await req.Model.findOne({ openid, date: today });
          if (data) {
            await calculateNutrition(data);
            model = await req.Model.findOneAndUpdate({ openid, date: today }, data, { new: true });
          }
        }
      } else if (req.Model.modelName === "Do" && req.body.sport !== undefined) {
        // Do 模型的更新且包含sport字段，重新计算运动消耗
        model = await req.Model.findOneAndUpdate({ openid }, req.body, { new: true });
        let data = await Do.findOne({ openid });
        await calculateSportBurn(data);
        model = await Do.findOneAndUpdate({ openid }, data, { new: true });
      } else {
        // 其他模型的普通更新
        model = await req.Model.findOneAndUpdate({ openid }, req.body, { new: true });
      }
    }
    
    res.send(model);
  } catch (err) {
    console.error('更新数据错误:', err);
    res.status(400).send({
      success: false,
      message: err.message || '更新数据失败'
    });
  }
}

/**
 * 获取数据
 */
async function getData(req, res) {
  try {
    const { openid, q, id } = req.query;
    let model;
    
    if (req.Model.modelName === "Food") {
      if (q) {
        // 搜索食物或运动
        let list = await req.Model.find({ name: q });
        let type = 0;
        if(list.length === 0) {
          list = await Sport.find({ name: q });
          type = 1;
        }
        model = {
          list,
          total: list.length,
          type,
        };
      } else if (id && id.trim()) {
        // 根据ID获取食物或运动详情
        model = await req.Model.findById(id);
        if(!model) {
          model = await Sport.findById(id);
        }
        if (model) {
          await Current.create({
            name: model.name,
            id,
          });
        }
      } else {
        return res.status(400).send({ error: '缺少 id 参数' });
      }
    } else if (req.Model.modelName === "User") {
      // 获取用户信息
      model = await req.Model.findOne({ openid });
    } else if (req.Model.modelName === "Eat") {
      // 获取饮食数据，支持按日期查询
      const { day } = req.query;
      const queryCondition = { openid };
      
      if (day) {
        // 查询指定日期的记录
        queryCondition.date = day;
      } else {
        // 查询今天的记录
        const today = new Date().toISOString().split('T')[0];
        queryCondition.date = today;
      }
      
      model = await req.Model.findOne(queryCondition);
      
      // 如果查询今天的记录但没有找到，创建一个新的空记录
      if (!model && !day) {
        const User = require("../../models/User");
        const userInfo = await User.findOne({ openid });
        
        if (userInfo) {
          const today = new Date().toISOString().split('T')[0];
          model = new req.Model({
            openid,
            date: today,
            data: today,
            eat_score: 0,
            exercise: 1.37, // 默认中度运动
            breakfast: [],
            lunch: [],
            dinner: [],
            snacks: [],
            score: {
              calorie_target: 0,
              fat_target: 0,
              carbohydrate_target: 0,
              protein_target: 0,
              calorie_today: 0,
              fat_today: 0,
              carbohydrate_today: 0,
              protein_today: 0,
            },
          });
          
          // 重新计算营养目标（基于用户信息）
          await calculateNutrition(model);
          await model.save();
          
          // 同时在 Date 表中添加日期记录
          try {
            await DateModel.create({ openid, date: today });
          } catch (err) {
            console.log('Date 记录创建失败（可能已存在）:', err.message);
          }
        }
      }
      
      // 填充食物详细信息（food_name, calorie等）
      if (model) {
        await populateFoodDetails(model);
      }
      
      // 如果需要详细的营养数据分布（用于环形图），计算各食物的营养贡献
      if (model && req.query.detail === 'true') {
        // console.log('[getData] 开始计算详细营养数据，openid:', openid);
        
        // 初始化营养数据结构
        const nutritionData = {
          date: model.date || new Date().toLocaleDateString(),
          eat_score: model.eat_score || 0,
          calorieData: { total: 0, series: [] },
          fatData: { total: 0, series: [] },
          carbohydrateData: { total: 0, series: [] },
          proteinData: { total: 0, series: [] }
        };
        
        // 合并所有餐次的食物
        const allMeals = [
          ...(model.breakfast || []),
          ...(model.lunch || []),
          ...(model.dinner || []),
          ...(model.snacks || [])
        ];
        
        // 计算每个食物的营养贡献
        for (const meal of allMeals) {
          if (!meal.food_id || !meal.eat_num) continue;
          
          try {
            const food = await Food.findById(meal.food_id);
            if (!food || !food.components) continue;
            
            // 找到对应的单位
            const component = food.components.find(c => c.unit_name === meal.unit_name);
            if (!component) continue;
            
            // 计算实际营养值（单位营养值 * 食用数量）
            const calorie = (component.calorie || 0) * meal.eat_num;
            const fat = (component.fat || 0) * meal.eat_num;
            const carbohydrate = (component.carbohydrate || 0) * meal.eat_num;
            const protein = (component.protein || 0) * meal.eat_num;
            
            const displayName = `${food.name}(${meal.unit_name}×${meal.eat_num})`;
            
            // 添加到热量数据
            if (calorie > 0) {
              nutritionData.calorieData.total += calorie;
              nutritionData.calorieData.series.push({
                name: displayName,
                data: Math.round(calorie)
              });
            }
            
            // 添加到脂肪数据
            if (fat > 0) {
              nutritionData.fatData.total += fat;
              nutritionData.fatData.series.push({
                name: displayName,
                data: Math.round(fat * 10) / 10
              });
            }
            
            // 添加到碳水数据
            if (carbohydrate > 0) {
              nutritionData.carbohydrateData.total += carbohydrate;
              nutritionData.carbohydrateData.series.push({
                name: displayName,
                data: Math.round(carbohydrate * 10) / 10
              });
            }
            
            // 添加到蛋白质数据
            if (protein > 0) {
              nutritionData.proteinData.total += protein;
              nutritionData.proteinData.series.push({
                name: displayName,
                data: Math.round(protein * 10) / 10
              });
            }
          } catch (err) {
            console.error(`获取食物 ${meal.food_id} 信息失败:`, err);
          }
        }
        
        // 四舍五入总计
        nutritionData.calorieData.total = Math.round(nutritionData.calorieData.total);
        nutritionData.fatData.total = Math.round(nutritionData.fatData.total * 10) / 10;
        nutritionData.carbohydrateData.total = Math.round(nutritionData.carbohydrateData.total * 10) / 10;
        nutritionData.proteinData.total = Math.round(nutritionData.proteinData.total * 10) / 10;
        
        // console.log('[getData] 营养数据计算完成:', JSON.stringify(nutritionData, null, 2));
        model = nutritionData;
      }
    } else if (req.Model.modelName === "Do") {
      // 获取运动数据
      model = await req.Model.findOne({ openid });
    } else if (req.Model.modelName === "Date") {
      // 获取用户的历史日期列表，按日期降序排列
      model = await req.Model.find({ openid }).sort({ date: -1 });
    } else if (
      req.Model.modelName === "Rank" ||
      req.Model.modelName === "Current"
    ) {
      model = await req.Model.find({ openid });
    }
    
    res.send(model);
  } catch (error) {
    console.error('API错误:', error);
    res.status(500).send({ error: error.message || '服务器错误' });
  }
}

module.exports = {
  updateData,
  getData
};

